In [ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import timedelta
from hhpy.plotting import animplot
In [2]:
# set pyplot rcParams
plt.rcParams['figure.figsize'] = (10,4)
In [3]:
# first let's make some data
df = pd.DataFrame({'x':np.linspace(0,99,1000)})

# start with a sine wave
df['y'] = np.sin(df['x'])*10
# timestamp
df['t'] = pd.to_datetime('2018-01-01')
# init list of dfs
dfs = [df]

for _i in range(30):    
    _df = dfs[_i].copy()
    # make the wave increase and shift
    _df['y'] = np.sin(_df['x']-_i)*10*(1+_i/100)
    # shift date by 1
    _df['t'] += timedelta(days=1)
    dfs.append(_df)
    del _df
    
df = pd.concat(dfs,ignore_index=True,sort=False)

del dfs

a simple plot can be generated by just calling the function with the data/x/y/z format

In [4]:
animplot(data=df,x='x',y='y',t='t',t_format='%Y-%m-%d')
Out[4]:


Once Loop Reflect

the parameter "mode" controls which object is returned. It can be set inside hhpy.plotting.rcParams

In [5]:
# matplotlib FuncAnimation object (can be saved with .save('FILENAME.mp4'))
print(animplot(data=df,x='x',y='y',t='t',t_format='%Y-%m-%d',mode='matplotlib'))
<matplotlib.animation.FuncAnimation object at 0x7f85d084a550>
In [6]:
# HTML5 Movie
animplot(data=df,x='x',y='y',t='t',t_format='%Y-%m-%d',mode='html')
Out[6]:
In [7]:
# Interactive JavaScript Widget (default)
animplot(data=df,x='x',y='y',t='t',t_format='%Y-%m-%d',mode='jshtml')
Out[7]:


Once Loop Reflect

kws are passed to pyplot.plot()

In [8]:
animplot(data=df,x='x',y='y',t='t',t_format='%Y-%m-%d',marker='o',ls='None',markerfacecolor='None',markeredgecolor='blue')
Out[8]:


Once Loop Reflect

a more complex plot can be generated by first drawing the figure, setting up the lines and passing them to animplot as a list of dictionaries

In [9]:
# calculate diff to plot on second subplot
df['y_diff'] = df['y'].diff()

# init list of dictionaries to be passed to animplot
lines = [{},{}]

fig, ax = plt.subplots(nrows=2,figsize=(12,9))

for _y in range(-10,11,5):
    ax[0].axhline(_y,ls=':',color='k',alpha=.5)
    ax[1].axhline(_y,ls=':',color='k',alpha=.5)

# linit lines
lines[0]['line'] = ax[0].plot([],[],label='y')[0]
lines[1]['line'] = ax[1].plot([],[],label='y_diff')[0]

# it is recommended to specify the axis for each line (if not it will try to infer)
lines[0]['ax'] = ax[0]
lines[1]['ax'] = ax[1]

# config
lines[0]['y'] = 'y'
lines[1]['y'] = 'y_diff'

# plot options - for legends it is a good idea to specify a position because 'best' tends to change over time
ax[0].legend(loc='upper right')
ax[1].legend(loc='upper right')

# call animplot, shared data doesn't have to be speficied by line
animplot(lines=lines,data=df,x='x',t='t',t_format='%Y-%m-%d',fig=fig,ax=ax)
Out[9]:


Once Loop Reflect

by default x and y limits are auto detected, if you don't want that you can set them by Hand.

You can either pass them with x_lim=...,y_lim=... (shared across subplots)

or set them beforehand and call the function with xlim=False, ylim=False

In [10]:
# due to the init as empty lines the plot does not have proper limits
ax[0].set_ylim([-15,15])
ax[1].set_ylim([-2,2])

# call animplot with y_lim = False
animplot(lines=lines,data=df,x='x',t='t',fig=fig,ax=ax,ylim=False)
Out[10]:


Once Loop Reflect
In [ ]: